知识点名称:百度地图(或者高德地图)API的使用
编号: K11-3
前驱知识点编号:K11-1,K11-2
作者:
讲义内容:
11.3.1 百度地图API使用基本步骤
百度地图 Android SDK是一套基于Android 2.1及以上版本设备的应用程序接口, 您可以通过该接口实现丰富的LBS功能:
地图:提供地图(2D、3D)的展示和缩放、平移、旋转、改变视角等地图操作;
室内图:提供展示公众建筑物室内地图的展示功能;
Android Wear:适配Android Wear,支持Android穿戴设备;
POI检索:可根据关键字,对POI数据进行周边、区域和城市内三种检索;
室内POI检索:支持设置城市和当前建筑物的室内POI检索;
地理编码:提供地理坐标和地址之间相互转换的能力;
线路规划:支持公交信息查询、公交换乘查询、驾车线路规划和步行路径检索;
覆盖物:提供多种地图覆盖物(自定义标注、几何图形、文字绘制、地形图图层、热力图图层等),满足开发者的各种需求;
定位:采用多种定位模式,使用定位SDK获取位置信息,使用地图SDK我的位置图层进行位置展示;
离线地图:支持使用离线地图,节省用户流量,同时为用户带来更好的地图体验;
调启百度地图:利用SDK接口,直接在本地打开百度地图客户端或WebApp,实现地图功能。
周边雷达:利用周边雷达功能,开发者可在App内低成本、快速实现查找周边使用相同App的用户位置的功能。
LBS云检索:支持用户检索存储在LBS云内的自有POI数据,并展示;
瓦片图层:支持开发者在地图上添加自有瓦片数据;
特色功能:提供短串分享、Place详情检索、热力图等特色功能,帮助开发者搭建功能更加强大的应用;
开发者可在百度地图Android SDK的下载页面下载到最新版的地图SDK,下载地址为: http://developer.baidu.com/map/index.php?title=androidsdk/sdkandev-download
1、申请密匙
百度地图Android平台API申请链接当前为http://lbsyun.baidu.com/apiconsole/key
具体步骤见:http://lbsyun.baidu.com/index.php?title=androidsdk/guide/key
- 配置环境及发布
Android Studio工程配置方法
第一步:在工程app/libs目录下放入baidumapapi_vX_X_X.jar包,在src/main/目录下新建jniLibs目录,工程会自动加载src目录下的so动态库,放入libBaiduMapSDK_vX_X_X_X.so如下图所示,注意jar和so的前3位版本号必须一致,并且保证使用一次下载的文件夹中的两个文件,不能不同功能组件的jar或so交叉使用。
so的配置也可以参考demo给出的目录结构,如下图所示,在app工程路径下,新建libs,并在libs目录下放入对应不同CPU架构的so文件。这样工程并不会自动加载libs下的so,需在gradle编译时,通过加入代码: jniLibs.srcDir 'libs' 来说明so的路径为该libs路径。
第二步:工程配置还需要把jar包集成到自己的工程中,如图上图所示,放入libs目录下。对于每个jar文件,右键-选择Add As Library,导入到工程中。对应在build.gradle生成工程所依赖的jar文件说明,如图所示:
应用混淆
集成地图SDK的应用,在打包混淆的时候,需要注意与地图SDK相关的方法不可被混淆。混淆方法如下:
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**
保证百度类不能被混淆,否则会出现网络不可用等运行时异常
百度地图SDK为开发者提供了便捷的显示百度地图数据的接口,通过以下几步操作,即可在您的应用中使用百度地图数据:
第一步:创建并配置工程(具体方法参见工程配置部分的介绍);
第二步:在AndroidManifest中添加开发密钥、所需权限等信息;
(1)在application中添加开发密钥
<application>
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="开发者 key" /> </application>
2)添加所需权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
第三步,在布局xml文件中添加地图控件;
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
第四步,在应用程序创建时初始化 SDK引用的Context 全局变量:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
}
}
注意:在SDK各功能组件使用之前都需要调用
SDKInitializer.initialize(getApplicationContext());,因此我们建议该方法放在Application的初始化方法中
第五步,创建地图Activity,管理地图生命周期;
public class MainActivity extends Activity {
MapView mMapView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.bmapView);
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
}
完成以上步骤后,运行程序,即可在您的应用中显示如下地图:
11.3.2 百度地图API之常见地图操作
地图可以包含一个或多个图层,每个图层在每个级别都是由若干个图块组成的,他们覆盖了地图的整个表面。例如您所看到的包括街道、兴趣点(POI)、学校、公园等内容的地图展现就是一个图层,另外交通流量的展现也是通过图层来实现的。
11.3.3 百度地图API之地图检索
POI检索
POI(Point of Interest),中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。
百度地图SDK提供三种类型的POI检索:周边检索、区域检索和城市内检索。
下面将以 城市内检索 为例,向大家介绍如何使用检索服务。
第一步,创建POI检索实例
mPoiSearch = PoiSearch.newInstance();
第二步,创建POI检索监听者;
OnGetPoiSearchResultListener poiListener = new OnGetPoiSearchResultListener(){
public void onGetPoiResult(PoiResult result){
//获取POI检索结果
}
public void onGetPoiDetailResult(PoiDetailResult result){
//获取Place详情页检索结果
} };
第三步,设置POI检索监听者;
mPoiSearch.setOnGetPoiSearchResultListener(poiListener);
第四步,发起检索请求;
mPoiSearch.searchInCity((new PoiCitySearchOption())
.city(“北京”)
.keyword(“美食”)
.pageNum(10));
第五步,释放POI检索实例;
mPoiSearch.destroy();
自v3.6.1开始,城市poi检索返回结果,新增门址类列表数据:
PoiSearch类的searchInCity(PoiCitySearchOption) 发起检索时返回的结果,增加门址类数据:PoiResult中新增getAllAddr()获取门址类列表,当isHasAddrInfo() 返回true时,除了原poi列表外,还包含门址结果。
例如:在“北京”搜索“上地十街1号”,除返回包含“上地十街1号”的poi列表以外,还包括地址为“上地十街1号”的明确门址。
POI详情信息的检索
以上向大家介绍了POI检索功能的使用方法,百度地图SDK 还向广大开发者开放了 POI详情信息的检索 ,为开发者提供更多的LBS数据支持。
POI详情检索的实现方式如下:
第一步,发起检索:
//uid是POI检索中获取的POI ID信息
mPoiSearch.searchPoiDetail((new PoiDetailSearchOption()).poiUid(uid));
第二步,设置结果监听:
public void onGetPoiDetailResult(PoiDetailResult result) {
if (result.error != SearchResult.ERRORNO.NO_ERROR) {
//详情检索失败
// result.error请参考SearchResult.ERRORNO
}
else {
//检索成功
}
}
公交信息检索
利用BusLineSearch方法,开发者可查询公交线路的详情信息,实现方式如下:
第一步,发起POI检索,获取相应线路的UID;
//以城市内检索为例,详细方法请参考POI检索部分的相关介绍
mSearch.searchInCity((new PoiCitySearchOption())
.city(“北京”)
.keyword(“717”);
第二步,在POI检索结果中判断该POI类型是否为公交信息;
public void onGetPoiResult(PoiResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
return;
}
//遍历所有POI,找到类型为公交线路的POI
for (PoiInfo poi : result.getAllPoi()) {
if (poi.type == PoiInfo.POITYPE.BUS_LINE ||poi.type == PoiInfo.POITYPE.SUBWAY_LINE) {
//说明该条POI为公交信息,获取该条POI的UID
busLineId = poi.uid;
break;
}
}
}
第三步,定义并设置公交信息结果监听者(与POI类似),并发起公交详情检索;
//如下代码为发起检索代码,定义监听者和设置监听器的方法与POI中的类似
mBusLineSearch.searchBusLine((new BusLineSearchOption()
.city(“北京”)
.uid(busLineId)));
行政区边界数据检索
自v3.7.0起,支持行政区边界数据检索。根据省、市、县(区)级行政区划名称,查询行政区划的详细边界信息。 下面以查询“北京市海淀区”的边界为例,介绍如何进行查询,实现方法如下:
mDistrictSearch = DistrictSearch.newInstance();
mDistrictSearch.searchDistrict(new DistrictSearchOption().cityName(city).districtName(district));//其中city表示城市名称,必填;
district表示区名称,可选。
11.3.4 百度地图API之地图标注
开发者可根据自己实际的业务需求,利用标注覆盖物,在地图指定的位置上添加标注信息。
具体实现方法如下:
//定义Maker坐标点
LatLng point = new LatLng(39.963175, 116.400244); //构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.icon_marka); //构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
.position(point)
.icon(bitmap); //在地图上添加Marker,并显示
mBaiduMap.addOverlay(option);
针对已经添加在地图上的标注,可采用如下方式进行手势拖拽:
第一步,设置可拖拽:
OverlayOptions options = new MarkerOptions()
.position(llA) //设置marker的位置
.icon(bdA) //设置marker图标
.zIndex(9) //设置marker所在层级
.draggable(true); //设置手势拖拽//将marker添加到地图上
marker = (Marker) (mBaiduMap.addOverlay(options));
第二步,设置监听方法:
//调用BaiduMap对象的setOnMarkerDragListener方法设置marker拖拽的监听
mBaiduMap.setOnMarkerDragListener(new OnMarkerDragListener() {
public void onMarkerDrag(Marker marker) {
//拖拽中
}
public void onMarkerDragEnd(Marker marker) {
//拖拽结束
}
public void onMarkerDragStart(Marker marker) {
//开始拖拽
}});
自v3.3.0版本起,SDK提供了给Marker增加动画的能力,具体实现方法如下:
// 通过marker的icons设置一组图片,再通过period设置多少帧刷新一次图片资源
ArrayList<BitmapDescriptor> giflist = new ArrayList<BitmapDescriptor>();
giflist.add(bdA);
giflist.add(bdB);
giflist.add(bdC);
OverlayOptions ooD = new MarkerOptions().position(pt).icons(giflist)
.zIndex(0).period(10);
mMarkerD = (Marker) (mBaiduMap.addOverlay(ooD));
针对已添加在地图上的标注覆盖物,可利用如下方法进行修改和删除操作:
marker.remove(); //调用Marker对象的remove方法实现指定marker的删除
自v3.6.0版本起,SDK提供了给加载Marker增加动画的能力,加载maker时包含两种加载动画方式:从地上生长和从天上落下。
以生长动画为例,具体实现方法如下:
MarkerOptions ooD = new MarkerOptions().position(llD).icons(giflist).zIndex(0).period(10);
if (animationBox.isChecked()) {
// 生长动画
ooD.animateType(MarkerAnimateType.grow);
}
Marker mMarkerD = (Marker) (mBaiduMap.addOverlay(ooD));
自v3.6.0版本起,SDK提供了给Marker设置透明度的方法,具体实现方法如下:
MarkerOptions ooA = new MarkerOptions().position(llD).icons(giflist).zIndex(0).period(10).alpha(0.5);
mBaiduMap.addOverlay(ooA);
检索结果覆盖物
针对检索功能模块(POI检索、线路规划等),地图SDK还对外提供相应的覆盖物来快速展示结果信息。这些方法都是开源的,开发者可根据自己的实际去求来做个性化的定制。
利用检索结果覆盖物展示POI搜索结果的方式如下:
第一步,构造自定义 PoiOverlay 类;
private class MyPoiOverlay extends PoiOverlay {
public MyPoiOverlay(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public boolean onPoiClick(int index) {
super.onPoiClick(index);
return true;
}
}
第二步,在POI检索回调接口中添加自定义的PoiOverlay;
public void onGetPoiResult(PoiResult result) {
if (result == null || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
mBaiduMap.clear();
//创建PoiOverlay
PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
//设置overlay可以处理标注点击事件
mBaiduMap.setOnMarkerClickListener(overlay);
//设置PoiOverlay数据
overlay.setData(result);
//添加PoiOverlay到地图中
overlay.addToMap();
overlay.zoomToSpan();
return;
}
}
运行结果如下:
11.3.5 百度地图API之热力图
热力图功能
热力图是用不同颜色的区块叠加在地图上描述人群分布、密度和变化趋势的一个产品,百度地图SDK将绘制热力图的能力为广大开发者开放,帮助开发者利用自有数据,构建属于自己的热力图,提供丰富的展示效果。
利用热力图功能构建自有数据热力图的方式如下:
第一步,设置颜色变化:
//设置渐变颜色值int[] DEFAULT_GRADIENT_COLORS = {Color.rgb(102, 225, 0), Color.rgb(255, 0, 0) };//设置渐变颜色起始值float[] DEFAULT_GRADIENT_START_POINTS = { 0.2f, 1f };//构造颜色渐变对象
Gradient gradient = new Gradient(DEFAULT_GRADIENT_COLORS, DEFAULT_GRADIENT_START_POINTS);
第二步,准备数据:
List<LatLng> randomList = new ArrayList<LatLng>();Random r = new Random();for (int i = 0; i < 500; i++) {
// 116.220000,39.780000 116.570000,40.150000
int rlat = r.nextInt(370000);
int rlng = r.nextInt(370000);
int lat = 39780000 + rlat;
int lng = 116220000 + rlng;
LatLng ll = new LatLng(lat / 1E6, lng / 1E6);
randomList.add(ll);
}
第三步,添加、显示热力图:
//在大量热力图数据情况下,build过程相对较慢,建议放在新建线程实现
HeatMap heatmap = new HeatMap.Builder()
.data(randomList)
.gradient(gradient)
.build();//在地图上添加热力图
mBaiduMap.addHeatMap(heatmap);
第四步,删除热力图:
heatmap.removeHeatMap();